package rpgnetworker;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;

import chat.ChatModel;
import chat.ChatModule;
import chat.ChatPanel;

import map.Map;
import map.MapData;
import map.MapDisplayPanel;
import map.MapLibrary;
import map.MapManipulationPanel;
import map.MapModule;
import networkedmodules.ModuleGroup;
import userdisplays.UserPanel;
import userdisplays.UserPanelGroup;
import users.User;
import users.UserGroup;
import users.UserPermissionEditPanel;
import users.UserPermissionsEditFrame;

public class RpgNetworker extends JFrame
{
    private static final long serialVersionUID = 1L;

    private ModuleGroup group;
    private JFrame userPermissionsFrame;
    private UserGroup userGroup;

    public RpgNetworker()
    {
        super("RPG Networker");
        setJMenuBar(new RpgNetworkerMenuBar());
        setLayout(new BorderLayout());
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void startLocalSession()
    {
        if (group != null)
            group.kill();
    }

    public void startClientSession(String ip, int portNumber)
    {
        if (group != null)
            group.kill();
        group = new ModuleGroup(ip, portNumber);
        userGroup = new UserGroup();
        userPermissionsFrame = new UserPermissionsEditFrame(userGroup);
        group.addModule(userGroup);
        User user = new User("Client", Color.BLUE);
        userGroup.addSelf(user);
        UserPanelGroup panelGroup = new UserPanelGroup(user);
        group.addModule(panelGroup);
        UserPanel clientPanel = new UserPanel(user);
        panelGroup.putPanel(user, clientPanel);

        // Map
        MapLibrary toast = new MapLibrary("sand_dirt_library_dos\\",
                "settings.txt");
        MapData data = new MapData(10, 10);
        Map m = new Map(data, toast);
        MapDisplayPanel panel = new MapDisplayPanel(m);
        MapModule mod = new MapModule(m);
        group.addModule(mod);
        mod.requestMap();

        getContentPane().removeAll();
        add(panelGroup.getPanel(), BorderLayout.EAST);
        add(new JScrollPane(panel), BorderLayout.CENTER);
        add(buildBottomBar(user, panel), BorderLayout.SOUTH);
        validate();
    }

    public void startHostSession(int portNumber)
    {
        if (group != null)
            group.kill();
        group = new ModuleGroup(portNumber);
        userGroup = new UserGroup();
        userPermissionsFrame = new UserPermissionsEditFrame(userGroup);
        group.addModule(userGroup);
        User user = new User("Host", Color.RED);
        user.getUserPermissions().setAllPermissions(true);
        userGroup.addSelf(user);
        UserPanelGroup panelGroup = new UserPanelGroup(user);
        group.addModule(panelGroup);
        UserPanel clientPanel = new UserPanel(user);
        panelGroup.putPanel(user, clientPanel);

        // Map
        MapLibrary toast = new MapLibrary("sand_dirt_library_dos\\",
                "settings.txt");
        MapData data = new MapData(10, 10);
        Map m = new Map(data, toast);
        MapDisplayPanel panel = new MapDisplayPanel(m);
        group.addModule(new MapModule(m));

        getContentPane().removeAll();
        add(panelGroup.getPanel(), BorderLayout.EAST);
        add(new JScrollPane(panel), BorderLayout.CENTER);
        add(buildBottomBar(user, panel), BorderLayout.SOUTH);
        validate();
    }
    
    private JPanel buildBottomBar(User user, MapDisplayPanel panel)
    {
        ChatModel model = new ChatModel(user);
        ChatModule cMod = new ChatModule(model);
        group.addModule(cMod);

        JPanel bottomBar = new JPanel();
        bottomBar.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 1;
        c.gridheight = 1;
        c.gridwidth = 1;
        c.anchor = GridBagConstraints.BASELINE_LEADING;
        c.fill = GridBagConstraints.BOTH;
        bottomBar.add(new MapManipulationPanel(panel), c);
        c.gridx = 1;
        c.gridy = 0;
        c.weightx = 0;
        c.insets = new Insets(5, 5, 5, 5);
        bottomBar.add(new ChatPanel(model), c);
        return bottomBar;
    }

    public static void main(String args[])
    {
        new RpgNetworker();
        new RpgNetworker();
    }

    private class RpgNetworkerMenuBar extends JMenuBar
    {
        private static final long serialVersionUID = 1L;

        public RpgNetworkerMenuBar()
        {
            JMenu file = new JMenu("File");
            JMenuItem clientConnect = new JMenuItem("Connect as Client");
            clientConnect.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent arg0)
                {
                    new Thread(new Runnable()
                    {
                        public void run()
                        {
                            JTextField field = new JTextField();
                            field.addAncestorListener(new AncestorListener()
                            {
                                public void ancestorAdded(AncestorEvent e)
                                {
                                    JComponent component = e.getComponent();
                                    component.requestFocusInWindow();
                                    component.removeAncestorListener(this);
                                }

                                public void ancestorMoved(AncestorEvent e)
                                {
                                }

                                public void ancestorRemoved(AncestorEvent e)
                                {
                                }
                            });
                            JOptionPane.showMessageDialog(null, field, "Host IP Address", JOptionPane.PLAIN_MESSAGE);
                            startClientSession(field.getText(), 2388);
                        }
                    }).start();
                }
            });
            JMenuItem hostConnect = new JMenuItem("Connect as Host");
            hostConnect.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent arg0)
                {
                    new Thread(new Runnable()
                    {
                        public void run()
                        {
                            startHostSession(2388);
                        }
                    }).start();
                }
            });
            file.add(clientConnect);
            file.add(hostConnect);
            add(file);
            JMenu users = new JMenu("Users");
            JMenuItem editPermissions = new JMenuItem("Permissions");
            editPermissions.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent arg0)
                {
                    userPermissionsFrame.getContentPane().removeAll();
                    userPermissionsFrame.getContentPane().add(new UserPermissionEditPanel(userGroup));
                    userPermissionsFrame.revalidate();
                    userPermissionsFrame.pack();
                    userPermissionsFrame.setVisible(true);
                }
            });
            users.add(editPermissions);
            add(users);
        }
    }
}
